#include <gtest/gtest.h>
#include <iostream>
#include <unordered_map>

/*
    假设程序有 2 个测试类 TestA、TestB，各含 2 个测试用例，整体执行流程如下：
    1. main() 中注册 TestEnv 并调用 RUN_ALL_TESTS()
    2. → TestEnv::SetUp() （全局初始化，仅1次）
    3. → TestA::SetUpTestCase() （TestA 类初始化）
    4. → TestA::Test1 的 SetUp() → 执行 Test1 → TestA::Test1 的 TearDown()
    5. → TestA::Test2 的 SetUp() → 执行 Test2 → TestA::Test2 的 TearDown()
    6. → TestA::TearDownTestCase() （TestA 类清理）
    7. → TestB::SetUpTestCase() （TestB 类初始化）
    8. → TestB::Test1 的 SetUp() → 执行 Test1 → TestB::Test1 的 TearDown()
    9. → TestB::Test2 的 SetUp() → 执行 Test2 → TestB::Test2 的 TearDown()
    10. → TestB::TearDownTestCase() （TestB 类清理）
    11. → TestEnv::TearDown() （全局清理，仅1次）
    12. RUN_ALL_TESTS() 结束，返回测试结果
*/


// 证明了在各个TEST_F中对该类内的成员变量操作是互不可见的，即每个TEST_F都有一份独立的变量
// class HashTestEnv1 : public testing::Test
// {
// public:
//     static void SetUpTestCase()
//     {
//         std::cout << "环境 1 第一个 TEST 之前调用\n";
//     }
//     static void TearDownTestCase()
//     {
//         std::cout << "环境 1 最后一个 TEST 之后调用\n";
//     }

// public:
//     std::unordered_map<std::string, std::string> dict;
// };
// TEST_F(HashTestEnv1, insert_test)
// {
//     std::cout << "环境 1,中间 insert 测试\n";
//     dict.insert(std::make_pair("Hello", "你好"));
//     dict.insert(std::make_pair("hello", "你好"));
//     dict.insert(std::make_pair("雷吼", "你好"));
//     auto it = dict.find("hello");
//     ASSERT_NE(it, dict.end());
// }
// TEST_F(HashTestEnv1, sizeof)
// {
//     std::cout << "环境 1,中间 size 测试\n";
//     ASSERT_GT(dict.size(), 0);
// }
// int main(int argc, char *argv[])
// {
//     testing::InitGoogleTest(&argc, argv);
//     return RUN_ALL_TESTS();
// }

class HashTestEnv2 : public testing::Test
{
public:
    static void SetUpTestCase()
    {
        std::cout << "环境 2 第一个 TEST 之前被调用,进行总体环境配置\n ";
    }
    static void TearDownTestCase()
    {
        std::cout << "环境 2 最后一个 TEST 之后被调用,进行总体环境清理\n ";
    }
    virtual void SetUp() override
    {
        std::cout << "环境 2 测试前:提前准备数据!!\n";
        dict.insert(std::make_pair("bye", "再见"));
        dict.insert(std::make_pair("see you", "再见"));
    }
    virtual void TearDown() override
    {
        std::cout << "环境 2 测试结束后:清理数据!!\n";
        dict.clear();
    }

public:
    std::unordered_map<std::string, std::string> dict;
};

TEST_F(HashTestEnv2, insert_test)
{
    std::cout << "环境 2,中间测试\n";
    dict.insert(std::make_pair("hello", "你好"));
    ASSERT_EQ(dict.size(), 3);
}
TEST_F(HashTestEnv2, size_test)
{
    std::cout << "环境 2,中间 size 测试\n";
    auto it = dict.find("hello");
    ASSERT_EQ(it, dict.end());
    ASSERT_EQ(dict.size(), 2);
}

int main(int argc, char *argv[])
{
    testing::InitGoogleTest(&argc, argv);

    return RUN_ALL_TESTS();
}






